package id.co.rho.scoring.cid.client.mvc;

import id.co.rho.scoring.cid.client.command.CommandDispatcherAsync;
import id.co.rho.scoring.cid.client.helper.AbstractModelMenu;
import id.co.rho.scoring.cid.client.helper.MenuFolder;
import id.co.rho.scoring.cid.client.helper.ModelMenuItem;
import id.co.rho.scoring.cid.client.helper.Resources;
import id.co.rho.scoring.cid.client.security.Credential;
import id.co.rho.scoring.cid.client.utils.NavigationMenuUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.Style;
import com.extjs.gxt.ui.client.data.BaseTreeModel;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.TreeModel;
import com.extjs.gxt.ui.client.event.EventType;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionService;
import com.extjs.gxt.ui.client.event.SourceSelectionChangedListener;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;
import com.extjs.gxt.ui.client.mvc.Dispatcher;
import com.extjs.gxt.ui.client.mvc.View;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.util.IconHelper;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanelSelectionModel;
import com.extjs.gxt.ui.client.widget.treepanel.TreeStyle;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.inject.Inject;

public class NavigationView extends View {
	private Credential credential;
	private TreePanel<ModelData> tree;
	private TreeStore<ModelData> treeStore;
	private ContentPanel navPanel;
	private ModelData corporateParent;
	private String title = "";
	private BaseTreeModel[] children;
	private NavigationMenuUtils menuUtil;
	private CommandDispatcherAsync commandDispatcherAsync;

	@Inject
	public NavigationView(Credential credential,
			CommandDispatcherAsync commandDispatcherAsync) {
		super(null);
		this.commandDispatcherAsync = commandDispatcherAsync;
		this.credential = credential;
		this.menuUtil = new NavigationMenuUtils();
		controller = new ViewController();
	}

	@Override
	protected void initialize() {
		// ------------------------------Navigasi
		// Panel------------------------------ //

		ModelData[] model = MenuFolder.getMenu();
		treeStore = new TreeStore<ModelData>();
		treeStore.add(Arrays.asList(model), true);

		tree = new TreePanel<ModelData>(treeStore) {
			@Override
			protected AbstractImagePrototype calculateIconStyle(ModelData model) {
				AbstractImagePrototype style = null;
				TreeNode node = findNode(model);
				TreeStyle ts = getStyle();
				AbstractImagePrototype image = ((AbstractModelMenu) model)
						.getImage();
				if (node.isLeaf()) {
					if (image != null) {
						style = image;
					} else {
						style = Resources.ICONS.delete();
					}
				} else {
					if (image != null) {
						if (isExpanded(model)) {
							style = image;
						} else {
							style = image;
						}
					} else {
						if (isExpanded(model)) {
							style = ts.getNodeOpenIcon();
						} else {
							style = ts.getNodeCloseIcon();
						}
					}
				}
				return style;
			}
		};

		tree.getSelectionModel().setSelectionMode(Style.SelectionMode.SINGLE);
		tree.getStyle().setLeafIcon(IconHelper.createStyle("icon-list"));
		tree.setAutoLoad(true);
		tree.setDisplayProperty("name");
		tree.setSelectionModel(new MyTreeGridSelectionModel());
		SelectionService.get().addListener(
				new SourceSelectionChangedListener(tree.getSelectionModel()));
		SelectionService.get().register(tree.getSelectionModel());
		SelectionService.get().addListener(
				new SelectionChangedListener<TreeModel>() {
					public void selectionChanged(
							SelectionChangedEvent<TreeModel> event) {
						List<TreeModel> sel = event.getSelection();
						if (sel.size() > 0) {
							TreeModel m = (TreeModel) event.getSelection().get(
									0);
							if (m != null && m instanceof ModelMenuItem) {
								Dispatcher.forwardEvent(((ModelMenuItem) m)
										.getEvent());
							}
						}
					}
				});
		navPanel = (ContentPanel) Registry.get(AppView.WEST_PANEL);
		navPanel.add(tree);
		navPanel.layout();
	}

	@Override
	protected void handleEvent(AppEvent appEvent) {
		EventType type = appEvent.getType();
		if (appEvent.getType().equals(AppEvents.Logout)) {
			MessageBox.confirm("Logout", "Are you sure want to logout ?",
					new Listener<MessageBoxEvent>() {
						@Override
						public void handleEvent(MessageBoxEvent be) {
							Button btn = be.getButtonClicked();
							if (Dialog.YES.equalsIgnoreCase(btn.getItemId())) {
								tree.collapseAll();
								navPanel.hide();
								Dispatcher.forwardEvent(AppEvents.MainLoginView);
							}
						}
					});
		}
		menuUtil.updateInboxCount(treeStore);
	}

	private void selectChild(int i, boolean supressEvent) {
		if (children.length > 0) {
			List<ModelData> selectedList = new ArrayList<ModelData>();
			selectedList.add(children[i]);

			MyTreeGridSelectionModel selectionModel = (MyTreeGridSelectionModel) tree
					.getSelectionModel();
			// selectionModel.setSelection(selectedList);
			selectionModel.doSelect(selectedList, false, supressEvent);
		}
		navPanel.layout();
	}

	private class ViewController extends Controller {
		public ViewController() {
			registerEventTypes(AppEvents.Init);
			registerEventTypes(AppEvents.HidePage);
			registerEventTypes(AppEvents.TabChange);
			registerEventTypes(AppEvents.Logout);
			registerEventTypes(AppEvents.LoginSuccess);
		}

		@Override
		public void handleEvent(AppEvent event) {
			forwardToView(NavigationView.this, event);
		}
	}

	public class MyTreeGridSelectionModel extends
			TreePanelSelectionModel<ModelData> {

		@Override
		public void doSelect(List<ModelData> models, boolean keepExisting,
				boolean supressEvent) {
			// TODO Auto-generated method stub
			super.doSelect(models, keepExisting, supressEvent);
		}

	}

}